<?php
abstract class Layout extends Control
{
    protected static $files = array();
    protected static $noPackJS = array();

    public function Layout()
    {
        parent::__construct();
        $this->AddCssJs();
    }

    protected function AddCssJs()
    {
        BaseConfig::GetInstance()->AddCss('base');
        BaseConfig::GetInstance()->AddSharedJs('jquery/jquery');
        BaseConfig::GetInstance()->AddSharedJs('jquery/hash');
        BaseConfig::GetInstance()->AddSharedJs('jquery/jquery.hash');
        BaseConfig::GetInstance()->AddSharedJs('prototype');
        BaseConfig::GetInstance()->AddSharedJs('scriptaculous/scriptaculous');
        BaseConfig::GetInstance()->AddSharedJs('scriptaculous/effects');
        BaseConfig::GetInstance()->AddSharedJs('scriptaculous/builder');
        BaseConfig::GetInstance()->AddSharedJs('scriptaculous/dragdrop');
        BaseConfig::GetInstance()->AddSharedJs('base');
        BaseConfig::GetInstance()->AddSharedJs('controls/BaseControl');
        BaseConfig::GetInstance()->AddSharedJs('controls/InputControl');
        BaseConfig::GetInstance()->AddSharedJs('controls/LabelInputControl');
        BaseConfig::GetInstance()->AddSharedJs('controls/FormControl');
        BaseConfig::GetInstance()->AddSharedJs('controls/LangEdit');
        BaseConfig::GetInstance()->AddCss('controls/modalbox');
        BaseConfig::GetInstance()->AddSharedJs('controls/modalbox');
    }

    public function AddJsFileNoPack($files, $config, $ext)
    {
        if (!$files) return;
        $files = explode(',', $files);
        foreach ($files as $file)
        {
            $file = trim($file).'.js';
            $url = 'URL_'.$ext;
            $path = $config->$url.FS.$file;
            self::$noPackJS[$path] = $path;
        }
    }

    public static function AddFile($files, $config, $type)
    {
        if (!$files) return;
        $files = explode(',', $files);
        $ext = strtolower($type);
        if ($ext == 'shared_js') $ext = 'js';
        foreach ($files as $file)
        {
            $file = trim($file).".$ext";
            $dir = 'DIR_'.$type;
            $path = $config->$dir.DS.$file;
            self::$files[$ext][$path] = $path;
        }
    }

    public function GetCombined($ext)
    {
        if (AppConfig::GetInstance()->JS_COMBINE_MODE)
        {
            $src = $this->CombineFile($ext);
            $out[] = call_user_func("Layout::Return$ext", $src);
        }
        else if (isset(self::$files[$ext]))
        {
            foreach (self::$files[$ext] as $file)
            {
                $src = $this->RenderFile($file);
                $out[] = call_user_func("Layout::Return$ext", $src);
            }
        }

        if ($ext == 'js')
        {
            foreach (self::$noPackJS as $file)
            {
                $out[] = self::ReturnJs($file);
            }
        }

        return implode("\n", $out);
    }

    public static function ReturnCss($src)
    {
        return "<link rel='stylesheet' type='text/css' href='$src' />";
    }

    public static function ReturnJs($src)
    {
        return "<script type='text/javascript' src='$src'></script>";
    }

    protected function CombineFile($ext)
    {
        $hash = $this->GetHash(self::$files[$ext]);
        $name = "$hash.$ext";
        $path = AppConfig::GetInstance()->DIR_CACHE.DS.$ext;
        $file = $path.DS.$name;
        if (!file_exists($file) || AppConfig::GetInstance()->IsClearCache())
        {
            FileHandler::MakeDir($path);
            FileHandler::Combine($file, self::$files[$ext]);
            $template = new Template($name, $path);
            $value = $template->Replace(AppConfig::GetInstance()->GetReplaceValues());
            $pack_method = "Pack$ext";
            $value = String::$pack_method($value);
            FileHandler::Write($file, $value);
        }
        return AppConfig::GetInstance()->URL_CACHE.FS.$ext.FS.$name;
    }

    protected function GetHash($files)
    {
        $time = null;
        foreach ($files as $file)
        {
            if (file_exists($file))
                $time .= filemtime($file);
        }
        return substr(md5($time), 0, 16);
    }

    protected function RenderFile($origin_file)
    {
        if (!file_exists($origin_file))
            return null;
        $file_name = basename($origin_file);
        $base_path = dirname($origin_file);

        $ext = FileHandler::GetExt($origin_file);
        $hash = filemtime($origin_file);
        $name = FileHandler::GetName($origin_file).".$hash.$ext";
        $path = AppConfig::GetInstance()->DIR_CACHE.DS.$ext;
        $file = $path.DS.$name;

        if (!file_exists($file) || AppConfig::GetInstance()->IsClearCache())
        {
            $template = new Template($file_name, $base_path);
            $value = $template->Replace(AppConfig::GetInstance()->GetReplaceValues());
            $pack_method = "Pack$ext";
            $value = String::$pack_method($value);
            FileHandler::MakeDir($path);
            FileHandler::Write($file, $value);
        }
        return AppConfig::GetInstance()->URL_CACHE.FS.$ext.FS.$name;
    }

    public function Render($body)
    {
        $this->Replace(array(
            'combined_css' => $this->GetCombined('css'),
            'combined_js' => $this->GetCombined('js'),
            'center' => Template::ReplaceArray(AppConfig::GetInstance()->GetReplaceValues(), $body),
            'GATrackingCode' => $this->GetGATrackingCode(),
        ));
        return parent::Render();
    }

    protected function GetGATrackingCode()
    {
        if (AppConfig::GetInstance()->APP_LIVE_MODE)
        {
            $ga = new GoogleAnalyticsTrackingCodeControl(SettingModel::Get('GOOGLE_ANALYTICS_TRACKING_ID'));
            return $ga->Render();
        }
    }
}
?>
